package org.acghub.config;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.acghub.config.command.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @Desc
 * @Author miyuki4j
 * @Date 2025/7/26/星期六 14:30
 * @Version 1.0
 */
public interface Command {

    CommandEnum type();

    default void init(String[] args) throws Exception{
        List<TableConfig.ConfigKeyEnum> misMatch = new ArrayList<>();
        for (TableConfig.ConfigKeyEnum configKey : type().getConfigKeys()) {
            boolean match = false;
            for (String arg : args) {
                if (configKey.match(arg)){
                    Object parsed = configKey.parse(arg);
                    TableConfig.put(configKey, parsed);
                    match = true;
                    break;
                }
            }
            if (!match && configKey.isRequired()){
                misMatch.add(configKey);
            }
        }
        if (!misMatch.isEmpty()) {
            throw new CommandParseException("缺少参数:" + misMatch.stream().map(TableConfig.ConfigKeyEnum::getValue).collect(Collectors.joining(",")));
        }
    }


    void execute() throws Exception;

    default void exit() {
    }

    @Getter
    enum CommandEnum {

        HELP("help", "查看命令") {
            @Override
            public Command create() {
                return new HelpCommand();
            }
        },

        CODE_GENERATE("generate_code", "代码生成",
                TableConfig.ConfigKeyEnum.ENCODING,
                TableConfig.ConfigKeyEnum.INPUT_DIR,
                TableConfig.ConfigKeyEnum.CODE_GENERATE_DIR,
                TableConfig.ConfigKeyEnum.CODE_GENERATE_PACKAGE_PREFIX,
                TableConfig.ConfigKeyEnum.CODE_GENERATOR_TYPE,
                TableConfig.ConfigKeyEnum.CODE_GENERATE_USE_LOMBOK,
                TableConfig.ConfigKeyEnum.FREEMARKER_TEMPLATE_DIR,
                TableConfig.ConfigKeyEnum.FREEMARKER_TEMPLATE_NAME){
            @Override
            public Command create() {
                return new GenerateCodeCommand();
            }
        },

        EXPORT_DATA("export_data", "数据导出",
                TableConfig.ConfigKeyEnum.ENCODING,
                TableConfig.ConfigKeyEnum.INPUT_DIR,
                TableConfig.ConfigKeyEnum.DATA_EXPORT_DIR,
                TableConfig.ConfigKeyEnum.DATA_EXPORT_TYPE, TableConfig.ConfigKeyEnum.EXPORT_JSON_PRETTY) {
            @Override
            public Command create() {
                return new ExportDataCommand();
            }
        },

        IMPORT_DATA("import_data", "数据导入到进程",
                TableConfig.ConfigKeyEnum.ENCODING,
                TableConfig.ConfigKeyEnum.DATA_IMPORT_DIR, TableConfig.ConfigKeyEnum.DATA_IMPORT_TYPE) {
            @Override
            public Command create() {
                return new ImportDataCommand();
            }
        },

        LOAD_CONF("load_conf", "配置加载到进程",
                TableConfig.ConfigKeyEnum.ENCODING,
                TableConfig.ConfigKeyEnum.DATA_IMPORT_DIR, TableConfig.ConfigKeyEnum.DATA_IMPORT_TYPE) {
            @Override
            public Command create() {
                return new LoadConfCommand();
            }
        },

        ;

        private final String value;

        private final String desc;

        private final TableConfig.ConfigKeyEnum[] configKeys;

        CommandEnum(String value, String desc, TableConfig.ConfigKeyEnum... configKeys) {
            this.value = value;
            this.desc = desc;
            this.configKeys = configKeys;
        }

        CommandEnum(String value, String desc) {
            this.value = value;
            this.desc = desc;
            this.configKeys = new TableConfig.ConfigKeyEnum[0];
        }

        public String usage() {
            return "-" + value + ": " + desc;
        }

        public boolean match(String value) {
            return StringUtils.startsWith(value, "-" + this.value);
        }

        public abstract Command create();
    }

}
